﻿using JigLibX.Collision;
using JigLibX.Geometry;
using JigLibX.Physics;
using Microsoft.Xna.Framework;

namespace Innovator
{
	public abstract class PhysicsObject : Component, I3DComponent
	{
		float mass = 1;
		public Body Body;
		public CollisionSkin CollisionSkin;
		public float Mass
		{
			get { return mass; }
			set
			{
				mass = value;
				Vector3 com = SetMass(value);
				if (CollisionSkin != null)
					CollisionSkin.ApplyLocalTransform(
						new JigLibX.Math.Transform(-com, Matrix.Identity));
			}
		}
		public Vector3 Position
		{
			get { return Body.Position; }
			set{ Body.MoveTo(value,Body.Orientation);}
		}
		public Matrix Rotation
		{
			get { return Body.Orientation; }
			set { Body.MoveTo(Body.Position, value); }
		}
		public Vector3 EulerRotation
		{
			get { return MathUtil.MatrixToVector3(Rotation); }
			set { Rotation = MathUtil.Vector3ToMatrix(value); }
		}
		public bool Immovable
		{
			get { return Body.Immovable; }
			set { Body.Immovable = value; }
		}
		public BoundingBox BoundingBox
		{
			get
			{
				if (Body.CollisionSkin != null)
					return Body.CollisionSkin.WorldBoundingBox;
				else
					return new BoundingBox(Position - Vector3.One,
						Position + Vector3.One);
			}
		}
		public Vector3 Scale
		{
			get { return Vector3.One; }
			set { }
		}
		public Vector3 Velocity
		{
			get { return Body.Velocity; }
			set { Body.Velocity = value; }
		}
		//constructor
		public PhysicsObject() : base() { }
		public PhysicsObject(GameScreen Parent) : base(Parent) { }
		protected void InitializeBody()
		{
			Body = new Body();
			CollisionSkin = new CollisionSkin(Body);
			Body.CollisionSkin = this.CollisionSkin;
			Body.EnableBody();
		}
		public Vector3 SetMass(float mass)
		{
			PrimitiveProperties primitiveProperties =
				new PrimitiveProperties(
					PrimitiveProperties.MassDistributionEnum.Solid,
					PrimitiveProperties.MassTypeEnum.Density, mass);
			float junk; Vector3 com; Matrix it, itCoM;
			CollisionSkin.GetMassProperties(primitiveProperties,
				out junk, out com, out it, out itCoM);
			Body.BodyInertia = itCoM;
			Body.Mass = junk;

			return com;
		}
		public void OffsetModel(Vector3 PositionOffset, Matrix RotationOffset)
		{
			CollisionSkin.ApplyLocalTransform(
				new JigLibX.Math.Transform(PositionOffset, RotationOffset));
		}
		public override void DisableComponent()
		{
			Body.DisableBody();
			base.DisableComponent();
		}
	}
}